/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package game.experts.combine;

import game.experts.Expert;
import java.util.List;

/**
 *
 * @author emanuele
 */
public class SSPHSPWeightHintedCombinerExpert extends SSPSlidingWindowHintedCombinerExpert {

    public int hspThresholdLength = 8;
    public int hspMaximumLength = 15;
    
    @Override
    protected double[] getWeightsForExpert(Expert e) {
        double[] weights = new double[this.current.input.length()];

        // Inizializza l'array
        for (int j = 0; j < weights.length; j++)
            weights[j] = 1.0;

        List<String> alignedHintsPredictions = this.getAlignedHintsPredictions(e);

        for (int i = 0; i < alignedHintsPredictions.size(); i++) {
            String alHintPred = alignedHintsPredictions.get(i);

            int endIdx = 0;
            while (true) {
                // Trova il successivo HSP partendo da endIdx del precedente HSP
                int[] startEndLength = this.getHSPSubstring(alHintPred, endIdx);
                int startIdx = startEndLength[0];
                if (startIdx == -1) // Ovvero non ha trovato altri HSP
                    break;
                endIdx = startEndLength[1];
                double length = startEndLength[2];

                double errors = this.getDifferences(alHintPred, this.current.hints.get(i).hitAlignedSec, startIdx, endIdx);
                errors += 0.5;
                double errorRate = errors / length;

                double weightForHint = this.weightFromErrorRate(errorRate);

                for (int j = startIdx; j < endIdx; j++)
                    weights[j] += weightForHint;
            }
        }
        
        return weights;
    }

    private int[] getHSPSubstring(String alHintPred, int stringStart) {
        int[] startEndLength = new int[3];

        int startIdx = -1;
        int endIdx = -1;
        int tmpStartIdx, tmpEndIdx;

        for (tmpStartIdx = stringStart; tmpStartIdx < alHintPred.length(); tmpStartIdx++) {
            if (alHintPred.charAt(tmpStartIdx) == '-')
                continue;

            for (tmpEndIdx = tmpStartIdx+1; tmpEndIdx < alHintPred.length(); tmpEndIdx++) {
                if (alHintPred.charAt(tmpEndIdx) == '-')
                    break;
                if (tmpEndIdx - tmpStartIdx == this.hspMaximumLength)
                    break;
            }

            if (tmpEndIdx - tmpStartIdx >= this.hspThresholdLength) {
                startIdx = tmpStartIdx;
                endIdx = tmpEndIdx;
                break;
            } else {
                tmpStartIdx = tmpEndIdx;
            }
        }

        startEndLength[0] = startIdx;
        startEndLength[1] = endIdx;
        startEndLength[2] = endIdx - startIdx;

        return startEndLength;
    }

}
